const puppeteer = require('puppeteer');
const cheerio = require('cheerio');
const fs = require('fs');
const path = require('path');
const moment = require('moment');

/**
 * 尝试查找系统中已安装的Chrome浏览器路径
 * @returns {string|null} Chrome浏览器路径或null
 */
function findChromePath() {
  const possiblePaths = [
    // Windows 路径
    'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe',
    'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe',
    // 其他可能的Windows路径
    'C:\\Program Files\\Google\\Chrome Beta\\Application\\chrome.exe',
    'C:\\Program Files\\Google\\Chrome Dev\\Application\\chrome.exe',
    'C:\\Program Files\\Google\\Chrome SxS\\Application\\chrome.exe',
    // Linux 路径
    '/usr/bin/google-chrome',
    '/usr/bin/chromium-browser',
    '/usr/bin/chromium',
    // macOS 路径
    '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',
    '/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary',
  ];

  for (const chromePath of possiblePaths) {
    try {
      // 检查文件是否存在
      if (fs.existsSync(chromePath)) {
        console.log(`找到Chrome浏览器: ${chromePath}`);
        return chromePath;
      }
    } catch (error) {
      // 忽略错误
    }
  }
  
  console.log('未找到Chrome浏览器，将使用Puppeteer内置的浏览器');
  return null;
}

/**
 * 百度热搜爬虫类
 */
class BaiduHotCrawler {
  constructor() {
    this.browser = null;
    this.page = null;
    this.baseUrl = 'https://www.baidu.com/';
    this.dataDir = path.join(process.cwd(), 'data');
    
    // 确保数据目录存在
    if (!fs.existsSync(this.dataDir)) {
      fs.mkdirSync(this.dataDir, { recursive: true });
    }
  }

  /**
   * 初始化浏览器
   */
  async initialize() {
    try {
      // 查找Chrome浏览器路径
      const chromePath = findChromePath();
      
      // 启动配置
      const launchOptions = {
        headless: "new", // 使用新的无头模式
        args: [
          '--no-sandbox', 
          '--disable-setuid-sandbox', 
          '--disable-gpu',
          '--window-size=1920,1080'
        ],
        ignoreHTTPSErrors: true
      };
      
      // 如果找到Chrome浏览器，使用它
      if (chromePath) {
        launchOptions.executablePath = chromePath;
      }
      
      // 启动浏览器
      this.browser = await puppeteer.launch(launchOptions);
      this.page = await this.browser.newPage();
      
      // 设置视口
      await this.page.setViewport({ width: 1920, height: 1080 });
      
      // 设置用户代理
      await this.page.setUserAgent('Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36');
      
      console.log('浏览器初始化成功');
    } catch (error) {
      console.error('浏览器初始化失败:', error);
      throw error;
    }
  }

  /**
   * 关闭浏览器
   */
  async close() {
    if (this.browser) {
      await this.browser.close();
      this.browser = null;
      this.page = null;
      console.log('浏览器已关闭');
    }
  }

  /**
   * 获取百度热搜列表
   * @returns {Promise<Array>} 热搜列表
   */
  async getHotSearchList() {
    try {
      console.log('正在获取百度热搜...');
      
      // 访问百度首页
      await this.page.goto(this.baseUrl, { 
        waitUntil: 'networkidle2',
        timeout: 30000 
      });
      
      // 等待热搜内容加载
      await this.page.waitForSelector('.s-hotsearch-content .hotsearch-item', { timeout: 10000 });
      
      // 截图保存
      const screenshotPath = path.join(this.dataDir, `baidu_hot_${Date.now()}.png`);
      await this.page.screenshot({ path: screenshotPath, fullPage: false });
      console.log(`已保存百度热搜截图: ${screenshotPath}`);
      
      // 获取页面内容
      const content = await this.page.content();
      const $ = cheerio.load(content);
      
      const hotSearchItems = [];
      
      // 提取热搜列表数据
      $('.s-hotsearch-content .hotsearch-item').each((index, element) => {
        const $element = $(element);
        const rank = $element.find('.title-index').text().trim();
        const title = $element.find('.title-content-title').text().trim();
        const hotValue = $element.find('.title-content-index').text().trim();
        const link = $element.attr('href');
        
        // 判断是否有热搜标记
        const isHot = $element.find('.hot-icon').length > 0;
        const isNew = $element.find('.new-icon').length > 0;
        
        hotSearchItems.push({
          rank,
          title,
          hotValue,
          link,
          isHot,
          isNew,
          timestamp: moment().format('YYYY-MM-DD HH:mm:ss')
        });
      });
      
      console.log(`成功获取 ${hotSearchItems.length} 条百度热搜`);
      return hotSearchItems;
    } catch (error) {
      console.error('获取百度热搜失败:', error);
      
      // 如果热搜元素选择器失败，尝试备用选择器
      try {
        console.log('尝试使用备用选择器...');
        
        // 不同时期百度可能会调整热搜的HTML结构，尝试多种选择器
        const backupSelectors = [
          '.s-news-rank-content .news-meta-item',
          '#hot-list .hot-item',
          '.s-rank-list .list-item'
        ];
        
        for (const selector of backupSelectors) {
          const exists = await this.page.evaluate((sel) => {
            return document.querySelectorAll(sel).length > 0;
          }, selector);
          
          if (exists) {
            console.log(`发现备用热搜选择器: ${selector}`);
            
            const content = await this.page.content();
            const $ = cheerio.load(content);
            
            const hotSearchItems = [];
            
            $(selector).each((index, element) => {
              const $element = $(element);
              
              // 尝试不同的子元素选择器
              const rank = $element.find('.index, .rank, .num').text().trim();
              const title = $element.find('.content, .title, .txt').text().trim();
              
              if (title) {
                hotSearchItems.push({
                  rank: rank || (index + 1).toString(),
                  title,
                  timestamp: moment().format('YYYY-MM-DD HH:mm:ss')
                });
              }
            });
            
            if (hotSearchItems.length > 0) {
              console.log(`使用备用选择器成功获取 ${hotSearchItems.length} 条热搜`);
              return hotSearchItems;
            }
          }
        }
        
        // 最后尝试通过搜索任何可能是热搜的内容
        const content = await this.page.content();
        const $ = cheerio.load(content);
        
        const potentialHotItems = [];
        
        $('a').each((index, element) => {
          const $element = $(element);
          const text = $element.text().trim();
          const href = $element.attr('href') || '';
          
          // 如果链接文本看起来像热搜项（短文本且有链接）
          if (text && text.length > 2 && text.length < 30 && href && (href.startsWith('http') || href.startsWith('/s'))) {
            potentialHotItems.push({
              rank: (index + 1).toString(),
              title: text,
              link: href,
              timestamp: moment().format('YYYY-MM-DD HH:mm:ss')
            });
          }
        });
        
        if (potentialHotItems.length > 0) {
          // 只返回最有可能是热搜的前20项
          const result = potentialHotItems.slice(0, 20);
          console.log(`通过通用方法找到 ${result.length} 条可能的热搜`);
          return result;
        }
      } catch (backupError) {
        console.error('备用方法也失败:', backupError);
      }
      
      // 如果所有方法都失败，返回空数组
      return [];
    }
  }

  /**
   * 保存热搜数据到本地文件
   * @param {Array} hotSearchList 热搜列表
   */
  async saveHotSearch(hotSearchList) {
    if (!hotSearchList || hotSearchList.length === 0) {
      console.log('没有热搜数据可保存');
      return null;
    }
    
    try {
      // 创建日期目录
      const dateStr = moment().format('YYYY-MM-DD');
      const dateDir = path.join(this.dataDir, dateStr);
      if (!fs.existsSync(dateDir)) {
        fs.mkdirSync(dateDir, { recursive: true });
      }
      
      // 创建时间戳文件名
      const timeStr = moment().format('HH-mm-ss');
      const fileName = `baidu_hot_${timeStr}.json`;
      const filePath = path.join(dateDir, fileName);
      
      // 写入JSON文件
      fs.writeFileSync(filePath, JSON.stringify(hotSearchList, null, 2), 'utf8');
      
      // 同时更新一个最新数据文件
      const latestFilePath = path.join(this.dataDir, 'latest_hot.json');
      fs.writeFileSync(latestFilePath, JSON.stringify(hotSearchList, null, 2), 'utf8');
      
      // 创建可读的文本文件版本
      const txtFilePath = path.join(dateDir, `baidu_hot_${timeStr}.txt`);
      let txtContent = `百度热搜榜 - ${moment().format('YYYY-MM-DD HH:mm:ss')}\n\n`;
      
      hotSearchList.forEach(item => {
        txtContent += `${item.rank}. ${item.title}`;
        if (item.hotValue) txtContent += ` (${item.hotValue})`;
        if (item.isHot) txtContent += ' [热]';
        if (item.isNew) txtContent += ' [新]';
        txtContent += '\n';
      });
      
      fs.writeFileSync(txtFilePath, txtContent, 'utf8');
      
      // 同时更新一个最新的文本文件
      const latestTxtPath = path.join(this.dataDir, 'latest_hot.txt');
      fs.writeFileSync(latestTxtPath, txtContent, 'utf8');
      
      console.log(`热搜数据已保存: ${filePath}`);
      return {
        jsonPath: filePath,
        txtPath: txtFilePath,
        count: hotSearchList.length
      };
    } catch (error) {
      console.error('保存热搜数据失败:', error);
      return null;
    }
  }

  /**
   * 执行完整的爬取流程
   */
  async crawl() {
    try {
      console.log('开始爬取百度热搜...');
      
      if (!this.browser) {
        await this.initialize();
      }
      
      const hotSearchList = await this.getHotSearchList();
      const result = await this.saveHotSearch(hotSearchList);
      
      return {
        success: true,
        data: hotSearchList,
        savedFiles: result,
        timestamp: moment().format('YYYY-MM-DD HH:mm:ss')
      };
    } catch (error) {
      console.error('爬取百度热搜失败:', error);
      return {
        success: false,
        message: error.message,
        timestamp: moment().format('YYYY-MM-DD HH:mm:ss')
      };
    } finally {
      await this.close();
    }
  }
}

module.exports = BaiduHotCrawler; 